package ferp.center.server.backend;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.taskqueue.TaskOptions;
import ferp.center.network.request.RequestProfileDelete;
import ferp.center.network.response.ResponseProfileDelete;
import ferp.center.server.Action;
import ferp.center.server.entity.Profile;
import ferp.center.server.entity.Rating;
import ferp.center.server.task.TaskRangeTreeRemoveRating;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.List;

/**
 * User: igorgok
 * Date: 5/10/12 4:07 PM
 */
public class ProfileDelete extends HttpServlet
{
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
  {
    // this is called by cron to delete inactive profiles
    // therefore, create inactive profile deletion task
    Action.queueTaskForBackend(response, "delete inactive profiles", "/profile/delete", new Action.AppendTaskOptions()
    {
      @Override
      public void execute(TaskOptions to)
      {
        // inactive
        to.param(PARAMETER_INACTIVE, "true");
      }
    });
  }

  @SuppressWarnings("unchecked")
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
  {
    // we get here either from device request or task
    if (request.getParameter(PARAMETER_INACTIVE) != null)
    {
      // delete inactive profiles
      Action.execute(request, response, Void.class, new Action.Read<Void, Void>()
      {
        public Void run(EntityManager em, Void input) throws IOException
        {
          Query q = em.createNamedQuery(Profile.QUERY_GET_INACTIVE);

          q.setParameter(1, new Date(System.currentTimeMillis() - INACTIVE_TIMEOUT));
          q.setMaxResults(CHUNK_SIZE);

          List<Profile> profiles = q.getResultList();

          for (Profile p : profiles)
          {
            // remove profile ratings from the ranking tree
            for (Rating r : p.getRatings())
              TaskRangeTreeRemoveRating.queue(r);

            // remove the profile itself (removes associated ratings as well)
            em.remove(p);
          }

          log("inactive profiles deleted: " + profiles.size());

          return null;
        }

        private final static long MONTH_IN_MS = 30 * 24 * 60 * 60 * 1000L;
        private final static long INACTIVE_TIMEOUT = 6 * MONTH_IN_MS;
        private final static int  CHUNK_SIZE = 1000;
      });
    }
    else
    {
      // delete specific profile
      Action.execute(request, response, RequestProfileDelete.class, new Action.Write<RequestProfileDelete, ResponseProfileDelete>()
      {
        public ResponseProfileDelete run(EntityManager em, RequestProfileDelete input) throws IOException
        {
          Key key = KeyFactory.createKey(Profile.class.getSimpleName(), input.id);
          Profile p = em.find(Profile.class, key);
          ResponseProfileDelete result = new ResponseProfileDelete();

          if (p != null)
          {
            // remove profile ratings from the ranking tree
            for (Rating r : p.getRatings())
              TaskRangeTreeRemoveRating.queue(r);

            em.remove(p);

            result.deleted = true;
          }

          return result;
        }
      });
    }
  }

  private static final String PARAMETER_INACTIVE = "inactive";
}
